#include "MaterialReader.h"
#include "StringUtil.h"

MaterialReader::MaterialReader(IniFile* gameConfig,tstring fileName):
m_GameConfig(gameConfig),
m_FileName(fileName),
m_ParentDir(StringUtil::GetParentDirectory(m_FileName))
{

}

MaterialReader::~MaterialReader(void)
{
	m_Materials.clear();
}

void MaterialReader::Read()
{
	m_Input.open(m_FileName.c_str());
	if ( !m_Input)
		return;
	tstring line;
	if (m_Input.is_open())
	{
		while (! m_Input.eof() )
		{
			getline (m_Input,line);
			if (line.find(_T("newmtl"),0) == 0 ){
				ReadMaterialName(line);
			}else if (line.find(_T("dx10shader"),0) == 0){
				ReadShader(line);
			}else if (line.find(_T("Ka"),0) == 0){
				ReadAmbientColor(line);
			}else if (line.find(_T("Kd"),0) == 0){
				ReadDiffuseColor(line);
			}else if (line.find(_T("Ks"),0) == 0){
				ReadSpecularColor(line);
			}else if (line.find(_T("d"),0) == 0 || line.find(_T("Tr"),0)== 0 ){
				ReadTransparancy(line);
			}else if ( line.find(_T("Ns"),0) == 0 ){
				ReadShininess(line);
			}else if ( line.find(_T("map_Kd"),0) == 0){
				ReadDiffuseTexture(line);
			}else if (line.find(_T("map_Ks"),0) == 0){
				ReadSpecularTexture(line);
			}else if (line.find(_T("map_Kn"),0) == 0){
				ReadNormalMapTexture(line);
			}
		}
		m_Input.close();
	}
}

DAEFloat3 MaterialReader::ReadColor(tstring& line){
	StringUtil::Split(line,_T(" "),m_ParseHelp);
	if ( m_ParseHelp.size() == 4){
		DAEFloat3 color;
		tstringstream sx(m_ParseHelp[1]);
		sx>>color.x;
		tstringstream sy(m_ParseHelp[2]);
		sy>>color.y;
		tstringstream sz(m_ParseHelp[3]);
		sz>>color.z;
		return color;
	}
	return DAEFloat3(0,0,0);
}

float MaterialReader::ReadFloat(tstring& line){
	StringUtil::Split(line,_T(" "),m_ParseHelp);
	if ( m_ParseHelp.size() == 2){
		float value;
		tstringstream svalue(m_ParseHelp[1]);
		svalue>>value;
		return value;
	}
	return 0.0f;
}

tstring MaterialReader::ReadString(tstring& line){
	StringUtil::Split(line,_T(" "),m_ParseHelp);
	if ( m_ParseHelp.size() == 2){
		return m_ParseHelp[1];
	}
	return _T("");
}

void MaterialReader::ReadMaterialName(tstring& line){
	StringUtil::Split(line,_T(" "),m_ParseHelp);
	if ( m_ParseHelp.size()==2){
		m_CurrentMaterial = new Material(m_ParseHelp[1]);
		m_Materials[m_CurrentMaterial->GetMaterialName()]=m_CurrentMaterial;
	}
}

void MaterialReader::ReadAmbientColor(tstring& line){
	if ( m_CurrentMaterial != NULL ){
		DAEFloat3 color = ReadColor(line);
		m_CurrentMaterial->SetAmbientColor(color);
	}
}

void MaterialReader::ReadDiffuseColor(tstring& line){
	if ( m_CurrentMaterial != NULL ){
		DAEFloat3 color = ReadColor(line);
		m_CurrentMaterial->SetDiffuseColor(color);
	}
}

void MaterialReader::ReadSpecularColor(tstring& line){
	if ( m_CurrentMaterial != NULL ){
		DAEFloat3 color = ReadColor(line);
		m_CurrentMaterial->SetSpecularColor(color);
	}
}

void MaterialReader::ReadTransparancy(tstring& line){
	if ( m_CurrentMaterial != NULL ){
		m_CurrentMaterial->SetAlpha(ReadFloat(line));
	}
}

void MaterialReader::ReadShininess(tstring& line){
	if (m_CurrentMaterial!= NULL){
		m_CurrentMaterial->SetShininess(ReadFloat(line));
	}
}

void MaterialReader::ReadDiffuseTexture(tstring& line){
	if ( m_CurrentMaterial != NULL){
		m_CurrentMaterial->SetDiffuseTexture(m_ParentDir + L"/" + ReadString(line));
	}
}

void MaterialReader::ReadSpecularTexture(tstring& line){
	if  (m_CurrentMaterial != NULL){
		m_CurrentMaterial->SetSpecularTexture(m_ParentDir + L"/" + ReadString(line));
	}
}

void MaterialReader::ReadNormalMapTexture(tstring& line){
	if ( m_CurrentMaterial != NULL){
		m_CurrentMaterial->SetNormalMapTexture(m_ParentDir + L"/" + ReadString(line));
	}
}

void MaterialReader::ReadShader(tstring& line){
	if ( m_CurrentMaterial != NULL){
		tstring baseDir = m_GameConfig->GetValue(_T("Export"),_T("baseDir"))+_T("/")+m_GameConfig->GetValue(_T("Export"),_T("textureDir"));
		m_CurrentMaterial->SetEffectFileName(ReadString(line));
	}
}

bool MaterialReader::HasMaterial(tstring& name)
{
	return m_Materials.find(name) != m_Materials.end();	
}

Material* MaterialReader::GetMaterial(tstring& name){
	if ( m_Materials.find(name) != m_Materials.end() ){
		return m_Materials[name];
	}
	return NULL;
}